package com.zhu.blog.controller;


import com.alibaba.fastjson.JSONObject;
import com.zhu.blog.handler.StateErrorException;
import com.zhu.blog.model.QQInfo;
import com.zhu.blog.prodriver.QQHttpClient;
import com.zhu.blog.service.QQService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

import javax.servlet.http.*;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

@Controller
public class QQController {

    @Autowired
    private QQService qqService;

    @Value("${qq.oauth.http}")
    private String http;
    @Value("${qq.appid}")
    private String APPID;
    @Value("${qq.appkey}")
    private String APPKEY;
    @Value("${cookie.time}")
    private Integer time;

    @GetMapping("/qq/oauth")
    public String qq(HttpSession session) throws UnsupportedEncodingException {
        //QQ互联中的回调地址
        String backUrl = http +"/qq/callback";
        //用户第三方应用防止CSRF攻击
        String uuid = UUID.randomUUID().toString().replace("-", "");
        session.setAttribute("state",uuid);

        //第一步：获取Authorization Code
        String url = "https://graph.qq.com/oauth2.0/authorize?response_type=code"+
                "&client_id=" + APPID +
                "&redirect_uri=" + URLEncoder.encode(backUrl,"UTF-8") +
                "&state=" + uuid;
        return "redirect:" + url;
    }

    //QQ回调
    @GetMapping("/qq/callback")
    public String qqCallBacK(HttpServletRequest request, HttpServletResponse response) throws Exception{
        HttpSession session = request.getSession();
        String code = request.getParameter("code");
        String state = request.getParameter("state");
        String uuid = (String) session.getAttribute("state");
        if(uuid != null){
            if(!uuid.equals(state)){
                throw new StateErrorException("QQ,state错误");
            }
        }

        //第二步：通过Authorization Code 获取AccessToken
        String backUrl = http + "/qq/callback";
        String url = "https://graph.qq.com/oauth2.0/token?grant_type=authorization_code"+
                "&client_id=" + APPID +
                "&client_secret=" + APPKEY  +
                "&code=" + code +
                "&redirect_uri=" + backUrl;

        String access_token = QQHttpClient.getAccessToken(url);

        //第三步：通过accesstoken获取回调后的 openid 值
        url = "https://graph.qq.com/oauth2.0/me?access_token=" + access_token;
        String openid = QQHttpClient.getOpenID(url);

        //第四步：通过accesstoken获取qq用户信息
        url = "https://graph.qq.com/user/get_user_info?access_token=" + access_token +
                "&oauth_consumer_key="+APPID +
                "&openid=" + openid;
        JSONObject jsonObject = QQHttpClient.getUserInfo(url);

        //设置cookie时间为2天
        Cookie cookie = new Cookie("JSESSIONID", session.getId());
        cookie.setPath(request.getContextPath() + "/");
        cookie.setMaxAge(time);
        response.addCookie(cookie);

        //可以存进mysql或者Redis中
        session.setAttribute("openid",openid); //openid,用来唯一标识qq用户
        session.setAttribute("nickname",removeNonBmpUnicode((String)jsonObject.get("nickname"))); //QQ网名
        session.setAttribute("avatar",(String)jsonObject.get("figureurl_qq")); //QQ头像url
        session.setAttribute("gender",(String)jsonObject.get("gender"));
        session.setAttribute("year",(String)jsonObject.get("year"));
        session.setAttribute("province",(String)jsonObject.get("province"));
        session.setAttribute("city",(String)jsonObject.get("city"));
        session.setAttribute("loginStatus","true");
        session.setAttribute("loginType",1); //登录方式，1 QQ，2 GitHub
        QQInfo qqUser = qqService.findQQUser(openid);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒SS毫秒 Ea z时区");
        //如果QQuser为空，自定义登陆时间存进数据库
        if(qqUser == null){
            session.setAttribute("firstLoginTime",simpleDateFormat.format(new Date()));
        }else {
        //如果QQuser不为空,从数据库中取出相应的数据
            session.setAttribute("firstLoginTime",qqUser.getLogintime());
            session.setAttribute("avatar",qqUser.getAvatar());
        }
        return "redirect:/qqinfo";
    }

    @GetMapping("/qqinfo")
    public String home(HttpSession session, Model model){
        String loginStatus =(String) session.getAttribute("loginStatus");
        //判断当前是否有QQ用户在登录
        if(loginStatus != null){
            String openid = (String) session.getAttribute("openid");
            String nickname = (String) session.getAttribute("nickname");
            String avatar = (String) session.getAttribute("avatar");
            String gender = (String) session.getAttribute("gender");
            String year = (String) session.getAttribute("year");
            String province = (String) session.getAttribute("province");
            String city = (String) session.getAttribute("city");
            String total = (String) session.getAttribute("total");
            String firstLoginTime = (String) session.getAttribute("firstLoginTime");
            model.addAttribute("openid",openid);
            model.addAttribute("nickname",nickname);
            model.addAttribute("avatar",avatar);
            model.addAttribute("gender",gender);
            model.addAttribute("year",year);
            model.addAttribute("province",province);
            model.addAttribute("city",city);
            model.addAttribute("total",total);
            model.addAttribute("firstLoginTime",firstLoginTime);

            return "qqinfo";
        }
        //如果未登录，重定向返回首页
        return "redirect:/index";
    }

    //前端传来的数据存进数据库中
    @PostMapping("/saveQQInfo")
    public String post(QQInfo qqInfo){
        QQInfo qqUser = qqService.findQQUser(qqInfo.getOpenid());
        //没有此数据，说明第一次登录，将数据存进数据库中
        if(qqUser == null){
            qqService.save(qqInfo);
            return "qqinfo";
        }
        return "qqinfo";
    }

    //退出登录
    @GetMapping("/qqlogout")
    public String logout(HttpSession session){
        session.removeAttribute("loginStatus");
        session.removeAttribute("avatar");
        session.removeAttribute("nickname");
        session.removeAttribute("openid");
        session.removeAttribute("loginType");
        return"redirect:/index";
    }

    //去除QQ用户名的特殊表情
    public String removeNonBmpUnicode(String str) {
        if (str == null) {
            return null;
        }
        str = str.replaceAll("[^\\u0000-\\uFFFF]", "");
        if ("".equals(str)) {
            str = "(* _ *)";
        }
        return str;
    }
}
